# GitHub Actions workflow file.
#
# For more information, visit
# https://docs.github.com/actions/learn-github-actions.

---
name: build

# Makes workflow run on any push or pull request.
on:
  pull_request:
    branches:
      - "**"
  push:
    branches:
      - "**"
  workflow_dispatch:
    inputs:
      debug:
        default: false
        description: Use Tmate session for debugging
        type: boolean
      job:
        default: test
        description: CI job to run
        options:
          - lint
          - test
        type: choice
      os:
        default: ubuntu
        description: Operating system for test job
        options:
          - macos
          - ubuntu
          - windows
        type: choice
      python:
        default: "3.11"
        description: Python version for test job
        options:
          - "3.8"
          - "3.9"
          - "3.10"
          - "3.11"
          - "3.12"
        type: choice

env:
  NPM_CONFIG_CACHE: "${{ github.workspace }}/.cache/npm"
  PIP_CACHE_DIR: "${{ github.workspace }}/.cache/pip"
  PIP_DISABLE_PIP_VERSION_CHECK: "true"
  PIP_ROOT_USER_ACTION: ignore
  POETRY_CACHE_DIR: "${{ github.workspace }}/.cache/pypoetry"
  POETRY_VIRTUALENVS_IN_PROJECT: "true"
  PYTHON_KEYRING_BACKEND: "keyring.backends.null.Keyring"

jobs:
  lint:
    if: ${{ github.event_name != 'workflow_dispatch' || inputs.job == 'lint' }}
    name: Check code with formatter and linter
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code repository
        uses: actions/checkout@v4
      - name: Cache packages
        uses: actions/cache@v4
        with:
          path: |
            .cache
            .venv
          key: >-
            node-20_python-3.11_${{ runner.os }}_npm-${{
            hashFiles('package-lock.json') }}_poetry-${{
            hashFiles('poetry.lock') }}
      - name: Install Node interpreter
        uses: actions/setup-node@v4
        with:
          node-version: "20"
      - name: Install Prettier formatter
        run: |
          node --version
          npm --version
          npm install --global prettier
      - name: Check configuration file formatting
        run: prettier --check .
      - name: Install Python interpreter
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Install Python packages
        run: |
          python --version
          python -m pip --version
          python -m pip install poetry
          poetry lock --check
          poetry install --verbose
      - name: Run linter checks
        run: |
          poetry run bandit -ilr src
          poetry run black --check .
          poetry run python scripts/build_docs.py
          poetry run flake8 .
          poetry run nbqa flake8 .
          poetry run mypy .
          poetry build
      - name: Setup Tmate session if debug enabled
        if: >-
          ${{ always() && github.event_name == 'workflow_dispatch' &&
          inputs.debug }}
        timeout-minutes: 60
        uses: mxschmitt/action-tmate@v3

  test:
    if: ${{ github.event_name != 'workflow_dispatch' || inputs.job == 'test' }}
    name: Run test suite for Python ${{ matrix.python }} on ${{ matrix.os }}
    strategy:
      fail-fast: false
      # Runs all job combinations on a manual run or any push or pull request to
      # the default branch. Runs only Python 3.11 Ubuntu job for all other Git
      # events.
      matrix:
        all:
          - >-
            ${{ github.ref == format('refs/heads/{0}',
            github.event.repository.default_branch) || github.base_ref ==
            github.event.repository.default_branch }}
        exclude:
          - all: false
        include:
          - os: ${{ inputs.os || 'ubuntu' }}
            python: ${{ inputs.python || '3.11' }}
        os:
          - macos
          - ubuntu
          - windows
        python:
          - "3.8"
          - "3.9"
          - "3.10"
          - "3.11"
          - "3.12"
    runs-on: ${{ matrix.os }}-latest
    steps:
      - name: Checkout code repository
        uses: actions/checkout@v4
      - name: Cache Python packages
        uses: actions/cache@v4
        with:
          path: |
            .cache
            .venv
          key: >-
            python-${{ matrix.python }}_${{ runner.os }}_poetry-${{
            hashFiles('poetry.lock') }}
      - name: Install Python interpreter
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}
      - name: Install Python packages
        run: |
          python --version
          python -m pip --version
          python -m pip install poetry
          poetry lock --check
          poetry install --verbose
      - name: Run test suite
        run: poetry run pytest --cov
      - name: Setup Tmate session if debug enabled
        if: >-
          ${{ always() && github.event_name == 'workflow_dispatch' &&
          inputs.debug }}
        timeout-minutes: 60
        uses: mxschmitt/action-tmate@v3
